Skip to content

feat(CombinatoryLogic): Partrec → SKI computability#403

Open
jessealama wants to merge 13 commits intoleanprover:mainfrom
jessealama:ski-equivalence
Open

feat(CombinatoryLogic): Partrec → SKI computability#403
jessealama wants to merge 13 commits intoleanprover:mainfrom
jessealama:ski-equivalence

Conversation

@jessealama
Copy link
Copy Markdown
Contributor

@jessealama jessealama commented Mar 6, 2026

Prove that every Nat.Partrec function on ℕ is SKI-computable (nat_partrec_ski_computable). Translates all eight Nat.Partrec.Code constructors to SKI terms and proves correctness, exercising the Recursion.lean infrastructure: primitive recursion (Rec), μ-recursion (RFind/RFindAbove), Nat pairing/unpairing, and integer square root.

Depends on leanprover-community/mathlib4#37521

Copy link
Copy Markdown
Contributor

@thomaskwaring thomaskwaring left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good to me! The title should probably say that only one direction of the equivalence is proven here (Partrec -> SKI). If I have time I can do a more thorough review but my only real concern would be whether the new version of primitive recursion could use the original one in Recursion.lean any more (though I would believe that the pair/unpair dance makes that impossible)

@jessealama jessealama changed the title feat(CombinatoryLogic): SKI ↔ Partrec equivalence feat(CombinatoryLogic): Partrec → SKI computability Mar 6, 2026
@jessealama
Copy link
Copy Markdown
Contributor Author

Looks pretty good to me! The title should probably say that only one direction of the equivalence is proven here (Partrec -> SKI). If I have time I can do a more thorough review but my only real concern would be whether the new version of primitive recursion could use the original one in Recursion.lean any more (though I would believe that the pair/unpair dance makes that impossible)

In an earlier version of this proof, I tried to apply the original recursor directly but gave up because it was getting too bulky. The new PrecTrans is essentially a custom wrapper around Rec for this proof. I'm happy to try to resurrect that earlier approach, or "hide" the PrecTrans if we don't want to expose it. At a minimum, I'll add more documentation to clarify what's going on with the new recursor.

@jessealama jessealama requested a review from thomaskwaring March 7, 2026 14:02
@thomaskwaring
Copy link
Copy Markdown
Contributor

In an earlier version of this proof, I tried to apply the original recursor directly but gave up because it was getting too bulky. The new PrecTrans is essentially a custom wrapper around Rec for this proof. I'm happy to try to resurrect that earlier approach, or "hide" the PrecTrans if we don't want to expose it. At a minimum, I'll add more documentation to clarify what's going on with the new recursor.

Makes sense! happy for you to leave as-is and/or hide the definition as you & the maintainers prefer. I suppose the ideal outcome would be for the definition of the term to mirror what the function looks like in Nat.Partrec, but that uses the monad structure on Part/PFun — once we have more API for encodings of datatypes I might try to update it, but that will be a way-away.

@jessealama
Copy link
Copy Markdown
Contributor Author

Converting to draft — splitting out the Sqrt/NatPair/NatUnpair layer as a smaller PR first: #445.

github-merge-queue bot pushed a commit that referenced this pull request Mar 20, 2026
…air (#445)

Implement SKI combinator terms for Nat.sqrt, Nat.pair, and Nat.unpair
with correctness proofs against Mathlib definitions.

Split out from #403 to make review easier.

---------

Co-authored-by: Chris Henson <46805207+chenson2018@users.noreply.github.com>
@chenson2018
Copy link
Copy Markdown
Collaborator

@jessealama Can you resolve the merge conflicts here please?

Prove that every Nat.Partrec function on ℕ is SKI-computable
(nat_partrec_ski_computable). Translates all eight Nat.Partrec.Code
constructors to SKI terms and proves correctness, exercising the
Recursion.lean infrastructure: primitive recursion (Rec), μ-recursion
(RFind/RFindAbove), Nat pairing/unpairing, and integer square root.
…ntions

Shorten verbose docstrings, collapse rw/have/subst patterns to obtain rfl,
extract inline calc blocks, and rename to camelCase (natPartrec_skiComputable,
rfindAbove_induction).
Only one direction (Partrec → SKI) is proven; rename file and section
header to avoid overclaiming equivalence. Remove unrelated SKIPartrec
stub (converse direction) to a separate branch.
Add computes_of_total and RFindAbove_unfold helpers to eliminate
repeated proof patterns. Simplify comp/pair_computes Part.mem chains
and rfindAbove_induction via early subst + local helper. Remove
dormant @[scoped grind] attributes from nil_correct and neg_correct.
Split the conjunction into `rfind_eval_root` (f evaluates to 0 at the
root) and `rfind_eval_pos_below` (f evaluates to nonzero below k).
@jessealama
Copy link
Copy Markdown
Contributor Author

@jessealama Can you resolve the merge conflicts here please?

Done! I'd like to leave this as a draft for now; I'm a bit unhappy with a couple of the proofs and will spend some time cleaning them up. I'm open to any suggestions, of course, but just as a matter of review priority, I'm happy to put this on your backburner.

Add RFindAbove_correct' which works with pointwise Church encoding
properties rather than requiring a total function. Restate the
original RFindAbove_correct as a corollary.
- Extract prec_computes and rfind_computes as standalone lemmas,
  making codeToSKINat_correct a uniform 1-2 line per case induction.
- Delete rfindAbove_induction (40 lines) by using the generalized
  RFindAbove_correct' from Recursion.lean.
- Add bind_eq_some helper to simplify Part.mem_bind_iff extraction
  boilerplate in comp_computes and prec_rec_correct.
@jessealama
Copy link
Copy Markdown
Contributor Author

@thomaskwaring I've done a bit of refactoring here that touches on Recursion.lean. I added a RFindAbove_correct' that works with pointwise Church encoding instead of requiring a total function. Your original RFindAbove_correct is now a corollary. What do you think?

Promote the private helper to Part.eq_some_of_bind_eq_some in a new
shared foundations file, making it available to other modules.
@jessealama jessealama marked this pull request as ready for review April 1, 2026 20:24
CI checkInitImports requires all Cslib modules to import Cslib.Init.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants